package pckg;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;

import pckg.RealLifeProperties;
import pckg.realRobot.RealRobot;
import pckg.realRobot.uC.UC.Side;


public class Main {

	private JFrame frame;
	private JTextField txtFieldCoordX;
	private JTextField txtFieldCoordY;
	private JTextField txtFieldVLStart;
	private JTextField txtFieldVRStart;
	private JTextField txtFieldOrientation;
	private JTextField txtFieldVLCom;
	private JTextField txtFieldVRCom;
	private JTextField txtFieldTime;
	private JTextField txtFieldCoordXFinal;
	private JTextField txtFieldCoordYFinal;
	private JTextField txtFieldVLFinal;
	private JTextField txtFieldVRFinal;
	private JTextField txtFieldOrientationFinal;

	private static RealRobot robot;
	private static RealRobot nnvRobot;
	private static RealRobot nnspRobot;
	private static RealRobot surfRobot;
	private JTextField txtFieldVLNext;
	private JTextField txtFieldVRNext;
	
	private final int precision = 5;
	
	private static myNeuralNetwork nnV;
	private static myNeuralNetwork nnSpV1;
	private static myNeuralNetwork nnSpV2;
	
	private static Surf surf;
	private static Decomposer decomposer;
	
	public static boolean vNN = false;
	public static boolean spNN = false;
	public static boolean surfB = true;
	public static boolean dec = false;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		
		//mlp = new MultiLayerPerceptron(TransferFunctionType.SIGMOID,10,10,10,1);
		//mlp.getLayerAt(3).getNeuronAt(0).setTransferFunction(new TransferFunnction )
		//mlp.getLayerAt(2).getNeuronAt(0).setTransferFunction(TransferFunctionType.SIGMOID);
		//mlp.save("prb.nnet");
		
		nnSpV1 = new myNeuralNetwork("netSpV1");
		nnSpV2 = new myNeuralNetwork("netSpV2");
		nnV = new myNeuralNetwork("6_10_10_10_2");
		surf = new Surf();
		decomposer = new Decomposer();
		Generator.testRandomSteps();
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main window = new Main();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Main() {
		initialize();
		robot = new RealRobot();
		nnvRobot = new RealRobot();
		nnvRobot.idealInc = false;
		nnspRobot = new RealRobot();
		nnspRobot.idealInc = false;
		surfRobot = new RealRobot();
		surfRobot.idealInc = false;
		
		//double[] inp = new double[]{0.9960,0.0243,0.1134,0.3210,2.4465,0.0400};
		//double[] out = nnSp.evaluate(inp);
	}
	
	public static RealRobot getRobot(){
		return robot;
	}
	
	public static RealRobot getSurfRobot(){
		return surfRobot;
	}
	
	public static RealRobot getNNvRobot(){
		return nnvRobot;
	}
	
	public static RealRobot getNNspRobot(){
		return nnspRobot;
	}

	public void calcButtonPressed(){
		//Generator.generateOneSample(robot);
		//Generator.generate(robot);
		//Generator.generateAllDirs(robot);
		//Generator.generateDirs(robot, 1, 1);
		//Generator.generateDirsWSt(robot, 1, 1);
		
		double x = getValue(txtFieldCoordX);
		double y = getValue(txtFieldCoordY);;
		double t = getValue(txtFieldTime);
		double orient = getValue(txtFieldOrientation);
		double vL = getValue(txtFieldVLStart);
		double vR = getValue(txtFieldVRStart);
		
		
		State startState = new State(new Vec(getValue(txtFieldCoordX),getValue(txtFieldCoordY)),
									getValue(txtFieldOrientation),
									getValue(txtFieldVRStart),
									getValue(txtFieldVLStart));
		
		if (0.000245*115200/255.0/2 > Math.abs(startState.vL)){
			startState.vL = 0;
		}
		if (0.000245*115200/255.0/2 > Math.abs(startState.vR)){
			startState.vR = 0;
		}
		
		int prevSpeedL = RealLifeProperties.vToSpeed(startState.vL);
		int prevSpeedR = RealLifeProperties.vToSpeed(startState.vR);
		
		if (0 == startState.vL){
			prevSpeedL = 255;
		}
		if (0 == startState.vR){
			prevSpeedR = 255;
		}
		
		RobotCommand cmd = new RobotCommand(getValue(txtFieldVLCom),
											getValue(txtFieldVRCom),
											(int) getValue(txtFieldTime),
											prevSpeedL,
											prevSpeedR);
		
		if (getValue(txtFieldVLCom) == 0 && getValue(txtFieldVRCom) == 0){
			cmd = RobotCommand.toZero(	prevSpeedL, 
										prevSpeedR, 
										robot.getDir(Side.LEFT), 
										robot.getDir(Side.RIGHT));
		}
		
		robot.runCmd(startState, cmd, null, false);
		
		//Surf.calcError(startState, cmd);
		
		State ideal = robot.getLastIdealState();
		
		System.out.println();
		// Calculating relative position
		x = ideal.pos.getX() - x;
		y = ideal.pos.getY() - y;
		double relOrient = RealLifeProperties.normalizeOrient(ideal.fi - orient);
		double dist = Math.sqrt(x*x+y*y);
		Vec newX = new Vec(Math.cos(orient),Math.sin(orient));
		Vec newY = new Vec(-1*newX.y,newX.x);
		Vec toPos = new Vec(x,y);
		
		Vec relPos = new Vec(	toPos.length()*Math.cos(relOrient),
								toPos.length()*Math.sin(relOrient) );
		
		orient = RealLifeProperties.normalizeOrient(ideal.fi - orient);
		
		txtFieldCoordXFinal.setText(trunc(Double.toString(robot.getX())));
		txtFieldCoordYFinal.setText(trunc(Double.toString(robot.getY())));
		txtFieldVLFinal.setText(trunc(Double.toString((RealLifeProperties.timerFrequency*(RealLifeProperties.StepDistanceMM/1000.0)/Math.abs(cmd.getSpeedL())/2.0))));
		txtFieldVRFinal.setText(trunc(Double.toString((RealLifeProperties.timerFrequency*(RealLifeProperties.StepDistanceMM/1000.0)/Math.abs(cmd.getSpeedR())/2.0))));
		txtFieldOrientationFinal.setText(trunc(Double.toString(robot.getOrient())));
		double[] inputNN;
		double[] outputNN = null;
		t = Generator.normT((int)t);
		x = relPos.x;
		y = relPos.y;
		double vLnn, vRnn;
	
		
		
		if (vNN){
			// V based NN 
			inputNN = new double[]{vL,vR,x,y,orient,t};
			outputNN = nnV.evaluate(inputNN);
			vLnn = outputNN[0];
			vRnn = outputNN[1];
			cmd = new RobotCommand(	vLnn,
									vRnn,
									(int) getValue(txtFieldTime),
									prevSpeedL,
									prevSpeedR);
			nnvRobot.runCmd(startState, cmd, null, false);
			
			System.out.println("V-NN output:");
			System.out.println("\tvL= " + trunc(vLnn) + "\n\tvR= " + trunc(vRnn));
		}
		
		if (spNN){
			// Speed based NN
			inputNN = new double[]{	Generator.normSp(prevSpeedL),
									Generator.normSp(prevSpeedR),
									x,y,orient,
									t};
			double[] outputV1 = nnSpV1.evaluate(inputNN);
			double[] outputV2 = nnSpV2.evaluate(inputNN);
			//outputNN[0] = nnSpV1.evaluate(inputNN);
			//outputNN[1] = nnSpV2.evaluate(inputNN);
			vLnn = RealLifeProperties.speedToV(Generator.denormSt(outputV1[0]));
			vRnn = RealLifeProperties.speedToV(Generator.denormSt(outputV2[0]));
			cmd = new RobotCommand(	vLnn,
									vRnn,
									(int) getValue(txtFieldTime),
									prevSpeedL,
									prevSpeedR);
			nnspRobot.runCmd(startState, cmd, null, false);
			System.out.println("Sp-NN output:");
			System.out.println("\tvL= " + trunc(vLnn) + "\n\tvR= " + trunc(vRnn));
		}
		
		if (surfB){
			
			
			// Surf
			cmd = new RobotCommand(getValue(txtFieldVLCom),
					getValue(txtFieldVRCom),
					(int) getValue(txtFieldTime),
					prevSpeedL,
					prevSpeedR);
			//Surf.writeSurfaceToFile(startState, cmd);
			cmd = surf.evaluate(startState, cmd);
			
			
			surfRobot.runCmd(startState, cmd, null, false);
		}
		
		if (dec){
			cmd = new RobotCommand(getValue(txtFieldVLCom),
					getValue(txtFieldVRCom),
					(int) getValue(txtFieldTime),
					prevSpeedL,
					prevSpeedR);
			decomposer.evaluate(startState, cmd);
		}
		
		
		frame.revalidate();
		frame.repaint();
	}
	
	public static RealRobot getDecRobot(){
		return decomposer.getRobot();
	}
	
	public void toStartingState(){
		
		txtFieldCoordX.setText(txtFieldCoordXFinal.getText());
		txtFieldCoordY.setText(txtFieldCoordYFinal.getText());
		txtFieldOrientation.setText(txtFieldOrientationFinal.getText());
		txtFieldVLStart.setText(txtFieldVLFinal.getText());
		txtFieldVRStart.setText(txtFieldVRFinal.getText());
		
		txtFieldVLCom.setText(Integer.toString(1));
		txtFieldVRCom.setText(Integer.toString(1));
		txtFieldTime.setText(Integer.toString(1000));
		
		txtFieldVLNext.setText(Integer.toString(0));
		txtFieldVRNext.setText(Integer.toString(0));
		
	}
	
	public void reset(){
		// 0.5867    0.0036   -0.1064    0.2981   -2.4584    0.8166    0.5730    0.0078
		txtFieldCoordX.setText("0");
		txtFieldCoordY.setText("0");
		txtFieldVLStart.setText("0");
		txtFieldVRStart.setText("0");
		txtFieldOrientation.setText("0");
		
		txtFieldVLCom.setText("1");
		txtFieldVRCom.setText("1");
		txtFieldTime.setText("1000");
		
		txtFieldCoordXFinal.setText("");
		txtFieldCoordYFinal.setText("");
		txtFieldOrientationFinal.setText("");
		txtFieldVLFinal.setText("");
		txtFieldVRFinal.setText("");
		robot.reset();
		nnvRobot.reset();
		nnspRobot.reset();
		surfRobot.reset();
		decomposer.resetRobot();
		frame.revalidate();
		frame.repaint();
	}
	
	public double getValue(JTextField field){
		return Double.parseDouble(field.getText());
	}
	
	public String trunc(double n){
		return trunc(Double.toString(n));
	}
	
	public String trunc(String s){
		String ret = s;
		
		int decimalIndex = s.indexOf('.');
		int eIndex = s.indexOf('E');
		
		if (decimalIndex != -1){
			ret = s.substring(0, Math.min(decimalIndex + precision, s.length()));
			if (eIndex != -1){
				ret = ret.concat(s.substring(s.length()-3, s.length()));
			}
		}
		
		return ret;
	}
	
	
	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setResizable(false);
		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
			    new KeyEventDispatcher() {
			        public boolean dispatchKeyEvent(KeyEvent e) {
			            if (e.getKeyChar() == KeyEvent.VK_ENTER && e.getID() == KeyEvent.KEY_PRESSED){
			            	calcButtonPressed();
			            	return false;
			            }
			            return false;
			        }
			    });
		frame.setBounds(100, 100, 1051, 570);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		frame.getContentPane().add(panel, BorderLayout.CENTER);
		panel.setLayout(null);
		
		JPanel inputPanel = new JPanel();
		inputPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		inputPanel.setBounds(10, 11, 535, 312);
		panel.add(inputPanel);
		inputPanel.setLayout(null);
		
		Simulator simulator = new Simulator();
		simulator.setBorder(new LineBorder(new Color(0, 0, 0)));
		simulator.setSize(480, 519);
		simulator.setLocation(555, 11);
		panel.add(simulator);
		simulator.setLayout(null);
		
		JLabel inputPanelLabel = new JLabel("Input");
		inputPanelLabel.setBounds(10, 11, 45, 17);
		inputPanelLabel.setFont(new Font("Tahoma", Font.BOLD, 14));
		inputPanelLabel.setHorizontalAlignment(SwingConstants.LEFT);
		inputPanel.add(inputPanelLabel);
		
		JButton btnCalculate = new JButton("Calculate");
		btnCalculate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				calcButtonPressed();
			}
		});
		btnCalculate.setBounds(10, 226, 515, 29);
		inputPanel.add(btnCalculate);
		
		JPanel StartingStatePanel = new JPanel();
		StartingStatePanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		StartingStatePanel.setBounds(10, 39, 515, 85);
		inputPanel.add(StartingStatePanel);
		StartingStatePanel.setLayout(null);
		
		JLabel lblStartingState = new JLabel("Starting state");
		lblStartingState.setHorizontalAlignment(SwingConstants.LEFT);
		lblStartingState.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblStartingState.setBounds(10, 11, 109, 17);
		StartingStatePanel.add(lblStartingState);
		
		JLabel lblCoordX = new JLabel("Coord X");
		lblCoordX.setHorizontalAlignment(SwingConstants.LEFT);
		lblCoordX.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblCoordX.setBounds(10, 34, 52, 17);
		StartingStatePanel.add(lblCoordX);
		
		JLabel lblCoordY = new JLabel("Coord Y");
		lblCoordY.setHorizontalAlignment(SwingConstants.LEFT);
		lblCoordY.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblCoordY.setBounds(117, 34, 52, 17);
		StartingStatePanel.add(lblCoordY);
		
		JLabel lblOrientation = new JLabel("Orientation");
		lblOrientation.setHorizontalAlignment(SwingConstants.LEFT);
		lblOrientation.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblOrientation.setBounds(429, 34, 90, 17);
		StartingStatePanel.add(lblOrientation);
		
		JLabel lblVleft_1 = new JLabel("V (left)");
		lblVleft_1.setHorizontalAlignment(SwingConstants.LEFT);
		lblVleft_1.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVleft_1.setBounds(224, 34, 52, 17);
		StartingStatePanel.add(lblVleft_1);
		
		JLabel lblVright_1 = new JLabel("V (right)");
		lblVright_1.setHorizontalAlignment(SwingConstants.LEFT);
		lblVright_1.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVright_1.setBounds(328, 34, 52, 17);
		StartingStatePanel.add(lblVright_1);
		
		txtFieldCoordX = new JTextField();
		txtFieldCoordX.setText("0");
		txtFieldCoordX.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldCoordX.setColumns(10);
		txtFieldCoordX.setBounds(10, 56, 76, 17);
		StartingStatePanel.add(txtFieldCoordX);
		
		txtFieldCoordY = new JTextField();
		txtFieldCoordY.setText("0");
		txtFieldCoordY.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldCoordY.setColumns(10);
		txtFieldCoordY.setBounds(117, 56, 76, 17);
		StartingStatePanel.add(txtFieldCoordY);
		
		txtFieldVLStart = new JTextField();
		txtFieldVLStart.setText("0");
		txtFieldVLStart.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVLStart.setColumns(10);
		txtFieldVLStart.setBounds(224, 56, 76, 17);
		StartingStatePanel.add(txtFieldVLStart);
		
		txtFieldVRStart = new JTextField();
		txtFieldVRStart.setText("0");
		txtFieldVRStart.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVRStart.setColumns(10);
		txtFieldVRStart.setBounds(328, 56, 76, 17);
		StartingStatePanel.add(txtFieldVRStart);
		
		txtFieldOrientation = new JTextField();
		txtFieldOrientation.setText("0");
		txtFieldOrientation.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldOrientation.setColumns(10);
		txtFieldOrientation.setBounds(429, 56, 76, 17);
		StartingStatePanel.add(txtFieldOrientation);
		
		JPanel CommandPanel = new JPanel();
		CommandPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		CommandPanel.setBounds(10, 135, 315, 80);
		inputPanel.add(CommandPanel);
		CommandPanel.setLayout(null);
		
		JLabel lblCommand = new JLabel("Command");
		lblCommand.setHorizontalAlignment(SwingConstants.LEFT);
		lblCommand.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblCommand.setBounds(10, 11, 109, 17);
		CommandPanel.add(lblCommand);
		
		JLabel lblVleft = new JLabel("V (left)");
		lblVleft.setHorizontalAlignment(SwingConstants.LEFT);
		lblVleft.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVleft.setBounds(10, 34, 52, 17);
		CommandPanel.add(lblVleft);
		
		JLabel lblVright = new JLabel("V (right)");
		lblVright.setHorizontalAlignment(SwingConstants.LEFT);
		lblVright.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVright.setBounds(117, 34, 52, 17);
		CommandPanel.add(lblVright);
		
		JLabel lblTime = new JLabel("Time (ms)");
		lblTime.setHorizontalAlignment(SwingConstants.LEFT);
		lblTime.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblTime.setBounds(224, 34, 62, 17);
		CommandPanel.add(lblTime);
		
		txtFieldVLCom = new JTextField();
		txtFieldVLCom.setText("1");
		txtFieldVLCom.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVLCom.setColumns(10);
		txtFieldVLCom.setBounds(10, 56, 76, 17);
		CommandPanel.add(txtFieldVLCom);
		
		txtFieldVRCom = new JTextField();
		txtFieldVRCom.setText("1");
		txtFieldVRCom.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVRCom.setColumns(10);
		txtFieldVRCom.setBounds(117, 56, 76, 17);
		CommandPanel.add(txtFieldVRCom);
		
		txtFieldTime = new JTextField();
		txtFieldTime.setText("1000");
		txtFieldTime.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldTime.setColumns(10);
		txtFieldTime.setBounds(224, 56, 76, 17);
		CommandPanel.add(txtFieldTime);
		
		JPanel nextCommandPanel = new JPanel();
		nextCommandPanel.setLayout(null);
		nextCommandPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		nextCommandPanel.setBounds(324, 135, 201, 80);
		inputPanel.add(nextCommandPanel);
		
		JLabel lblNextCmd = new JLabel("Next Command");
		lblNextCmd.setHorizontalAlignment(SwingConstants.LEFT);
		lblNextCmd.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblNextCmd.setBounds(10, 11, 109, 17);
		nextCommandPanel.add(lblNextCmd);
		
		JLabel lblVLNext = new JLabel("V (left)");
		lblVLNext.setHorizontalAlignment(SwingConstants.LEFT);
		lblVLNext.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVLNext.setBounds(10, 34, 52, 17);
		nextCommandPanel.add(lblVLNext);
		
		JLabel lblVRNext = new JLabel("V (right)");
		lblVRNext.setHorizontalAlignment(SwingConstants.LEFT);
		lblVRNext.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVRNext.setBounds(111, 34, 52, 17);
		nextCommandPanel.add(lblVRNext);
		
		txtFieldVLNext = new JTextField();
		txtFieldVLNext.setText("0");
		txtFieldVLNext.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVLNext.setColumns(10);
		txtFieldVLNext.setBounds(10, 56, 76, 17);
		nextCommandPanel.add(txtFieldVLNext);
		
		txtFieldVRNext = new JTextField();
		txtFieldVRNext.setText("0");
		txtFieldVRNext.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVRNext.setColumns(10);
		txtFieldVRNext.setBounds(111, 56, 76, 17);
		nextCommandPanel.add(txtFieldVRNext);
		
		JButton resetButton = new JButton("Reset");
		resetButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				reset();
			}
		});
		resetButton.setBounds(10, 267, 515, 29);
		inputPanel.add(resetButton);
		
		JPanel outputPanel = new JPanel();
		outputPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		outputPanel.setBounds(10, 347, 535, 183);
		panel.add(outputPanel);
		outputPanel.setLayout(null);
		
		JLabel outputPanelLabel = new JLabel("Output");
		outputPanelLabel.setBounds(10, 11, 54, 17);
		outputPanelLabel.setHorizontalAlignment(SwingConstants.LEFT);
		outputPanelLabel.setFont(new Font("Tahoma", Font.BOLD, 14));
		outputPanel.add(outputPanelLabel);
		
		JPanel endingStatePanel = new JPanel();
		endingStatePanel.setLayout(null);
		endingStatePanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		endingStatePanel.setBounds(10, 39, 515, 80);
		outputPanel.add(endingStatePanel);
		
		JLabel lblEndingState = new JLabel("Ending state");
		lblEndingState.setHorizontalAlignment(SwingConstants.LEFT);
		lblEndingState.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblEndingState.setBounds(10, 11, 109, 17);
		endingStatePanel.add(lblEndingState);
		
		JLabel lblCoordXFinal = new JLabel("Coord X");
		lblCoordXFinal.setHorizontalAlignment(SwingConstants.LEFT);
		lblCoordXFinal.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblCoordXFinal.setBounds(10, 34, 52, 17);
		endingStatePanel.add(lblCoordXFinal);
		
		JLabel lblCoordYFinal = new JLabel("Coord Y");
		lblCoordYFinal.setHorizontalAlignment(SwingConstants.LEFT);
		lblCoordYFinal.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblCoordYFinal.setBounds(117, 34, 52, 17);
		endingStatePanel.add(lblCoordYFinal);
		
		JLabel lblOrientationFinal = new JLabel("Orientation");
		lblOrientationFinal.setHorizontalAlignment(SwingConstants.LEFT);
		lblOrientationFinal.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblOrientationFinal.setBounds(429, 34, 90, 17);
		endingStatePanel.add(lblOrientationFinal);
		
		JLabel lblVLFinal = new JLabel("V (left)");
		lblVLFinal.setHorizontalAlignment(SwingConstants.LEFT);
		lblVLFinal.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVLFinal.setBounds(224, 34, 52, 17);
		endingStatePanel.add(lblVLFinal);
		
		JLabel lblVRFinal = new JLabel("V (right)");
		lblVRFinal.setHorizontalAlignment(SwingConstants.LEFT);
		lblVRFinal.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblVRFinal.setBounds(328, 34, 52, 17);
		endingStatePanel.add(lblVRFinal);
		
		txtFieldCoordXFinal = new JTextField();
		txtFieldCoordXFinal.setEditable(false);
		txtFieldCoordXFinal.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldCoordXFinal.setColumns(10);
		txtFieldCoordXFinal.setBounds(10, 56, 76, 17);
		endingStatePanel.add(txtFieldCoordXFinal);
		
		txtFieldCoordYFinal = new JTextField();
		txtFieldCoordYFinal.setEditable(false);
		txtFieldCoordYFinal.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldCoordYFinal.setColumns(10);
		txtFieldCoordYFinal.setBounds(117, 56, 76, 17);
		endingStatePanel.add(txtFieldCoordYFinal);
		
		txtFieldVLFinal = new JTextField();
		txtFieldVLFinal.setEditable(false);
		txtFieldVLFinal.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVLFinal.setColumns(10);
		txtFieldVLFinal.setBounds(224, 56, 76, 17);
		endingStatePanel.add(txtFieldVLFinal);
		
		txtFieldVRFinal = new JTextField();
		txtFieldVRFinal.setEditable(false);
		txtFieldVRFinal.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldVRFinal.setColumns(10);
		txtFieldVRFinal.setBounds(328, 56, 76, 17);
		endingStatePanel.add(txtFieldVRFinal);
		
		txtFieldOrientationFinal = new JTextField();
		txtFieldOrientationFinal.setEditable(false);
		txtFieldOrientationFinal.setHorizontalAlignment(SwingConstants.CENTER);
		txtFieldOrientationFinal.setColumns(10);
		txtFieldOrientationFinal.setBounds(429, 56, 76, 17);
		endingStatePanel.add(txtFieldOrientationFinal);
		
		JButton toStartingStateButton = new JButton("To Starting State");
		toStartingStateButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				toStartingState();
			}			
		});
		toStartingStateButton.setBounds(10, 143, 515, 29);
		outputPanel.add(toStartingStateButton);
	}
}
